/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE").
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR
 * COPYRIGHT LAW IS PROHIBITED.
 *
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE
 * MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 *
 */
package l1j.server.server.model;

import java.util.ArrayList;
import java.util.List;


import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.server.Config;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_HPMeter;
import l1j.server.server.serverpackets.S_Party;
import l1j.server.server.serverpackets.S_ServerMessage;

// Referenced classes of package l1j.server.server.model:
// L1Party

public class L1Party {
	private final List<L1PcInstance> _membersList = new ArrayList<L1PcInstance>();
	private L1PcInstance _leader = null;
//	private int _LogPartyId;
	/** 隊伍暫時鎖定 */
	private boolean _partylock;
	private boolean _isLeader = false;// 隊長已經加入

	/** 新增隊員 */
	public void addMember(final L1PcInstance pc) {
		if (pc == null) {
			throw new NullPointerException();
		}
		if (this._membersList.size() == Config.MAX_PT) {
			pc.sendPackets(new S_ServerMessage(417)); // これ以上パーティーメンバーを受け入れることはできません。
//			pc.setLogPartyId(0);// opqlo
			return;
		}
		if (this._membersList.contains(pc)) {
			return;
		}

		if (this._membersList.isEmpty()) {
			// 最初のPTメンバーであればリーダーにする
			this.setLeader(pc);
//			this._LogPartyId = pc.getId();// opqlo
//			TeamLog.getInstance().AddPartyList(this._LogPartyId, this);
		}
		pc.setParty(this);
		this._membersList.add(pc);
		
		for (final L1PcInstance member : _membersList) {
			if (!member.equals(_leader)) {// member不是隊長 發送UI資訊
//				member.sendPackets(new S_Party(pc , this));
				member.sendPackets(new S_Party(member , this));
			}else{
				if (_isLeader) {// 隊長已經載入
					// 發送隊員訊息給隊長UI
					member.sendPackets(new S_Party(pc));
				}
			}
		}
		if (!_isLeader) {
			_isLeader = true;
		}


//		this.showAddPartyInfo(pc);
		this.createMiniHp(pc);
		pc.sendPackets(new S_Party(this , pc));
		
//		if(Config.USE_L1J){
			pc.startRefreshParty();
//		}
//		pc.setLogPartyId(this._LogPartyId);// opqlo
	}

	/** 解散隊伍 */
	private synchronized void breakup() {
		final L1PcInstance[] members = this.getMembers();
//		TeamLog.getInstance().RemovePartyList(this._LogPartyId);// opqlo
		for (final L1PcInstance member : members) {
			this.removeMember(member);
//			member.setLogPartyId(0);
			member.sendPackets(new S_ServerMessage(418)); // パーティーを解散しました。
		}
	}

	/** 發送血條 */
	private void createMiniHp(final L1PcInstance pc) {
		if (_membersList.isEmpty()) {
			return;
		}
		if (_membersList.size() <= 0) {
			return;
		}
		// パーティー加入時、相互にHPを表示させる
		final L1PcInstance[] members = this.getMembers();

		for (final L1PcInstance member : members) {
			if (!pc.equals(member)) {
				// member 不是自己 發送自己的HP資訊列
				member.sendPackets(new S_HPMeter(pc.getId(), 100* pc.getCurrentHp() / pc.getMaxHp()));
				// 加載對方的HP資訊列
				pc.sendPackets(new S_HPMeter(member.getId(), 100* member.getCurrentHp() / member.getMaxHp()));
			}
		}
	}

	/** 停止發送血條 */
	private void deleteMiniHp(final L1PcInstance pc) {
		if (_membersList.isEmpty()) {
			return;
		}
		if (_membersList.size() <= 0) {
			return;
		}
		// パーティー離脱時、HPバーを削除する。
		final L1PcInstance[] members = this.getMembers();
		for (final L1PcInstance member : members) {
			pc.sendPackets(new S_HPMeter(member.getId(), 0xff));
			member.sendPackets(new S_HPMeter(pc.getId(), 0xff));
		}
	}

	/** 取得隊長 */
	public L1PcInstance getLeader() {
		return this._leader;
	}

	public boolean getLock() {
		return this._partylock;
	}

	/** 取得隊伍中所有成員 */
	public L1PcInstance[] getMembers() {
		return this._membersList.toArray(new L1PcInstance[this._membersList.size()]);
	}

	/** 取得員名單 */
	public String getMembersNameList() {
		String _result = new String("");
		for (final L1PcInstance pc : this._membersList) {
			_result = _result + pc.getName() + " ";
		}
		return _result;
	}

	/** 取得該隊員之隊伍編號 */
	public int getNumOfMembers() {
		return this._membersList.size();
	}

	/** 還有多少空缺 */
	public int getVacancy() {
		return Config.MAX_PT - this._membersList.size();
	}

	/** 使否為隊長 */
	public boolean isLeader(final L1PcInstance pc) {
		return pc.getId() == this._leader.getId();
	}

	/** 是否為成員 */
	public boolean isMember(final L1PcInstance pc) {
		return this._membersList.contains(pc);
	}

	/** 是否有空缺 */
	public boolean isVacancy() {
		return this._membersList.size() < Config.MAX_PT;
	}

	/** 驅逐隊員 */
	public void kickMember(final L1PcInstance pc) {
		if (this.getNumOfMembers() == 2) {
			// パーティーメンバーが自分とリーダーのみ
			this.breakup();
		} else {
			this.removeMember(pc);
//			pc.setLogPartyId(0);// opqlo
			for (final L1PcInstance member : this.getMembers()) {
				this.sendLeftMessage(member, pc);
			}
			this.sendKickMessage(pc);
		}
	}

	/** 離開隊伍 */
	public void leaveMember(final L1PcInstance pc) {
		if (this.getNumOfMembers() == 2) {
			// パーティーリーダーの場合
			this.breakup();

		} else {
			if (this.isLeader(pc)) {
				this.passLeader(this.getMembers()[1]);
			}
			this.removeMember(pc);
			for (final L1PcInstance member : this.getMembers()) {
				this.sendLeftMessage(member, pc);
			}
			this.sendLeftMessage(pc, pc);
			// パーティーリーダーでない場合
			/*
			 * if (getNumOfMembers() == 2) { // パーティーメンバーが自分とリーダーのみ
			 * removeMember(pc); L1PcInstance leader = getLeader();
			 * removeMember(leader); sendLeftMessage(pc, pc);
			 * sendLeftMessage(leader, pc); } else { // 残りのパーティーメンバーが２人以上いる
			 * removeMember(pc); for (L1PcInstance member : members) {
			 * sendLeftMessage(member, pc); } sendLeftMessage(pc, pc); }
			 */
		}
	}

	/** 隊長轉移 */
	public void passLeader(final L1PcInstance pc) {
		this.setLeader(pc);
//		TeamLog.getInstance().ChangeLeader(this._LogPartyId, pc.getId(), this);// opqlo
//		this._LogPartyId = pc.getId();
		for (final L1PcInstance member : this.getMembers()) {
			member.sendPackets(new S_Party(106, pc));
//			member.setPartyID(this._LogPartyId);// opqlo
		}
	}

	/** 移除隊員 */
	private void removeMember(final L1PcInstance pc) {
		if (!this._membersList.contains(pc)) {
			return;
		}
		 pc.stopRefreshParty();
		this._membersList.remove(pc);
		pc.setParty(null);
		if (!this._membersList.isEmpty()) {
			this.deleteMiniHp(pc);
		}
	}

	/** 發送驅逐訊息 */
	private void sendKickMessage(final L1PcInstance kickpc) {
		kickpc.sendPackets(new S_ServerMessage(419));
	}

	/** 發送小視窗訊息!? (未確定) */
	private void sendLeftMessage(final L1PcInstance sendTo,
			final L1PcInstance left) {
		// %0がパーティーから去りました。
		sendTo.sendPackets(new S_ServerMessage(420, left.getName()));
	}

	/** 設定隊長 */
	private void setLeader(final L1PcInstance pc) {
		this._leader = pc;
	}

	public void setLock(final boolean i) {
		this._partylock = i;
	}

//	/** 隊伍列表新增訊息 */
//	private void showAddPartyInfo(final L1PcInstance pc) {
//		for (final L1PcInstance member : this.getMembers()) {
//			if (pc.getId() == this.getLeader().getId()
//					&& this.getNumOfMembers() == 1) {
//				continue;
//			}
//			// TODO 發送給隊長的封包
//			if (pc.getId() == member.getId()) {
//				pc.sendPackets(new S_Party(104, pc));
//			} else {// TODO 其他成員封包
//				member.sendPackets(new S_Party(105, pc));
//			}
//			member.sendPackets(new S_Party(110, member));
//			this.createMiniHp(member);
//		}
//	}

	/** 更新血條 */
	public void updateMiniHP(final L1PcInstance pc) {
		if (_membersList.isEmpty()) {
			return;
		}
		if (_membersList.size() <= 0) {
			return;
		}
		final L1PcInstance[] members = this.getMembers();
		int HpRatio = 0;
		try{
			HpRatio = (int) (100 * pc.getCurrentHp() / pc.getMaxHp());
		}catch(Exception e){
			_log.log(Level.SEVERE, e.getLocalizedMessage() , e);
		}
		for (final L1PcInstance member : members) { // パーティーメンバー分更新
			member.sendPackets(new S_HPMeter(pc.getId(), HpRatio));
		}
	}

	private static final Logger _log = Logger.getLogger(L1Party.class.getName());

}
